package com.rasou.filter;

import io.github.resilience4j.bulkhead.Bulkhead;
import io.github.resilience4j.bulkhead.BulkheadConfig;
import io.github.resilience4j.bulkhead.BulkheadRegistry;
import io.vavr.control.Try;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.time.Duration;
import java.util.function.Supplier;

@Activate(group = CommonConstants.PROVIDER, order = -100)
public class RateLimitFilter implements Filter {

    private BulkheadRegistry bulkheadRegistry;

    public RateLimitFilter() {
        BulkheadConfig config = BulkheadConfig.custom()
                .maxConcurrentCalls(0)
                .maxWaitDuration(Duration.ofMillis(100))
                .build();

        bulkheadRegistry =
                BulkheadRegistry.of(config);
    }

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        String resource = invocation.getTargetServiceUniqueName() + "#" + invocation.getMethodName();


        System.out.println(System.currentTimeMillis() + resource);
        Bulkhead bulkhead = bulkheadRegistry
                .bulkhead(resource);
        Supplier<Result> supplier = Bulkhead
                .decorateSupplier(bulkhead, () -> invoker.invoke(invocation));
        return Try.ofSupplier(supplier).getOrElseThrow(() -> new RpcException("bulk exception"));
    }
}
